#include <cstdio>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>

#define INITIAL_POOL_SIZE 1024  // 初始内存池大小
#define BLOCK_SIZE 64           // 每个内存块的大小
#define NUM_THREADS 10          // 线程数量
#define ALLOCATIONS_PER_THREAD 100  // 每个线程的分配次数

// 内存池结构
typedef struct MemoryPool
{
    char *pool;               // 动态分配的内存池
    void **free_list;         // 空闲内存块链表
    size_t block_size;        // 内存块大小
    size_t block_count;       // 当前内存块数量
    size_t free_count;        // 当前空闲内存块数量
    size_t total_size;        // 总内存池大小
    pthread_mutex_t lock;     // 互斥锁，保护内存池的线程安全
} MemoryPool;

// 内存池初始化函数
void memory_pool_init(MemoryPool *mp, size_t initial_size)
{
    mp->block_size = BLOCK_SIZE;
    mp->block_count = initial_size / BLOCK_SIZE;
    mp->total_size = initial_size;
    mp->free_count = mp->block_count;

    // 动态分配内存池和空闲链表
    mp->pool = (char *) malloc(initial_size);
    mp->free_list = (void **) malloc(mp->block_count * sizeof(void *));

    if (!mp->pool || !mp->free_list)
    {
        printf("Memory allocation failed!\n");
        exit(EXIT_FAILURE);
    }

    // 初始化空闲链表
    for (size_t i = 0; i < mp->block_count; i++)
    {
        mp->free_list[i] = &mp->pool[i * mp->block_size];
    }

    // 初始化互斥锁
    pthread_mutex_init(&mp->lock, NULL);
}

// 内存分配函数
void *memory_pool_alloc(MemoryPool *mp)
{
    pthread_mutex_lock(&mp->lock);  // 加锁保护
    if (mp->free_count == 0)
    {
        // 如果没有空闲块，扩展内存池
        size_t new_size = mp->total_size * 2;
        char *new_pool = (char *) realloc(mp->pool, new_size);
        if (!new_pool)
        {
            pthread_mutex_unlock(&mp->lock);  // 解锁
            printf("Failed to expand memory pool!\n");
            return NULL;
        }

        // 更新内存池和链表
        mp->pool = new_pool;
        mp->free_list = (void **) realloc(mp->free_list, (mp->block_count * 2) * sizeof(void *));
        if (!mp->free_list)
        {
            pthread_mutex_unlock(&mp->lock);  // 解锁
            printf("Failed to expand free list!\n");
            return NULL;
        }

        // 初始化新增加的内存块
        for (size_t i = mp->block_count; i < 2 * mp->block_count; i++)
        {
            mp->free_list[mp->free_count++] = &mp->pool[i * mp->block_size];
        }

        mp->total_size = new_size;
        mp->block_count *= 2;
    }

    // 获取一个空闲内存块
    void *block = mp->free_list[--mp->free_count];
    pthread_mutex_unlock(&mp->lock);  // 解锁
    return block;
}

// 内存释放函数
void memory_pool_free(MemoryPool *mp, void *ptr)
{
    if (ptr == NULL)
    {
        return;
    }

    pthread_mutex_lock(&mp->lock);  // 加锁保护
    mp->free_list[mp->free_count++] = ptr;
    pthread_mutex_unlock(&mp->lock);  // 解锁
}

// 内存池销毁函数
void memory_pool_destroy(MemoryPool *mp)
{
    pthread_mutex_lock(&mp->lock);  // 加锁保护
    free(mp->pool);
    free(mp->free_list);
    mp->pool = NULL;
    mp->free_list = NULL;
    mp->free_count = 0;
    mp->block_count = 0;
    mp->total_size = 0;
    pthread_mutex_unlock(&mp->lock);  // 解锁

    // 销毁互斥锁
    pthread_mutex_destroy(&mp->lock);
}

// 测试用的全局内存池
MemoryPool global_memory_pool;

// 线程执行的任务：分配和释放内存
void *thread_function(void *arg)
{
    for (int i = 0; i < ALLOCATIONS_PER_THREAD; ++i)
    {
        // 分配内存
        void *block = memory_pool_alloc(&global_memory_pool);
        if (block)
        {
            printf("Thread %ld allocated block: %p\n", pthread_self(), block);

            // 模拟使用内存
            usleep(100);  // 暂停一小段时间，模拟并发操作

            // 释放内存
            memory_pool_free(&global_memory_pool, block);
            printf("Thread %ld freed block: %p\n", pthread_self(), block);
        }
        else
        {
            printf("Thread %ld failed to allocate memory\n", pthread_self());
        }
    }
    return NULL;
}

int main()
{
    // 初始化内存池
    memory_pool_init(&global_memory_pool, INITIAL_POOL_SIZE);

    // 创建线程
    pthread_t threads[NUM_THREADS];
    for (int i = 0; i < NUM_THREADS; ++i)
    {
        if (pthread_create(&threads[i], NULL, thread_function, NULL) != 0)
        {
            perror("Failed to create thread");
            exit(EXIT_FAILURE);
        }
    }

    // 等待线程完成
    for (int i = 0; i < NUM_THREADS; ++i)
    {
        pthread_join(threads[i], NULL);
    }

    // 销毁内存池
    memory_pool_destroy(&global_memory_pool);

    printf("All threads completed. Memory pool destroyed.\n");
    return 0;
}
